package cn.com.anypay.manager.common.validation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

/**
 * 身份证号格式验证器实现
 */
public class IdCardFormatValidator implements ConstraintValidator<IdCardFormat, String> {

    private boolean allowEmpty;
    private boolean strictMode;
    private boolean allow15Digits;

    // 18位身份证号正则表达式
    private static final String ID_CARD_18_PATTERN = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
    
    // 15位身份证号正则表达式
    private static final String ID_CARD_15_PATTERN = "^[1-9]\\d{5}\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}$";

    // 校验位权重
    private static final int[] WEIGHTS = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    
    // 校验位对应表
    private static final char[] CHECK_CODES = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

    @Override
    public void initialize(IdCardFormat constraintAnnotation) {
        this.allowEmpty = constraintAnnotation.allowEmpty();
        this.strictMode = constraintAnnotation.strictMode();
        this.allow15Digits = constraintAnnotation.allow15Digits();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 空值检查
        if (value == null || value.trim().isEmpty()) {
            return allowEmpty;
        }

        // 去除空格
        String cleanIdCard = value.replaceAll("\\s", "").toUpperCase();

        // 长度检查
        if (cleanIdCard.length() == 18) {
            return validate18DigitIdCard(cleanIdCard);
        } else if (cleanIdCard.length() == 15 && allow15Digits) {
            return validate15DigitIdCard(cleanIdCard);
        }

        return false;
    }

    /**
     * 验证18位身份证号
     */
    private boolean validate18DigitIdCard(String idCard) {
        // 基本格式验证
        if (!Pattern.matches(ID_CARD_18_PATTERN, idCard)) {
            return false;
        }

        // 严格模式下进行校验位验证
        if (strictMode) {
            return validateCheckDigit(idCard);
        }

        return true;
    }

    /**
     * 验证15位身份证号
     */
    private boolean validate15DigitIdCard(String idCard) {
        return Pattern.matches(ID_CARD_15_PATTERN, idCard);
    }

    /**
     * 验证18位身份证号的校验位
     */
    private boolean validateCheckDigit(String idCard) {
        try {
            int sum = 0;
            for (int i = 0; i < 17; i++) {
                sum += Character.getNumericValue(idCard.charAt(i)) * WEIGHTS[i];
            }
            
            int checkIndex = sum % 11;
            char expectedCheckCode = CHECK_CODES[checkIndex];
            char actualCheckCode = idCard.charAt(17);
            
            return expectedCheckCode == actualCheckCode;
        } catch (Exception e) {
            return false;
        }
    }
}